package conditionsAPI;

import java.util.ArrayList;
import java.util.Iterator;

class Condition{
	
	protected boolean state;
	protected String id;
	protected ArrayList<ConditionListener> conditionListeners;
	protected DomainCondition domainCondition;
	
	protected Condition(String id) throws ConditionDuplicatedException{
		this.id = id;
		this.conditionListeners = new ArrayList<ConditionListener>();
		this.state = false;
		ConditionsConfiguration.addCondition(this);
	}
	
	protected Condition(){
		this.conditionListeners = new ArrayList<ConditionListener>();
		this.state = false;
	}
	
	public String getId(){
		return this.id;
	}
	
	public boolean isTrue(){
		return this.state;
	}
	
	public void setDomainCondition(DomainCondition domainCondition){
		this.domainCondition = domainCondition;
	}
	
	public DomainCondition getDomainCondition(){
		return this.domainCondition;
	}
		
	public void updateState(Object domainObject){
		if (this.checkConditionState(domainObject)){
			setState(true);
		}
	}
	
	public void resetState(){
		domainCondition.resetState();
	}
	
	@Override
	public String toString(){
		return this.id;
	}
	
	@Override
	public boolean equals(Object object){
		Condition condition = (Condition) object;
		return this.id.equals(condition.id);
	}
	
	/**
	 * Notifica a todos los listeners que se modifico el estado de una 
	 * de las validaciones
	 * @param condition validacion cuyo estado se modifico.
	 */
	protected void fireConditionChange(Condition condition){
		Iterator<ConditionListener> conditionListenersIterator = this.conditionListeners.iterator();
		while (conditionListenersIterator.hasNext()){
			ConditionListener conditionListener = conditionListenersIterator.next();
			conditionListener.onConditionStateUpdated(condition);
		}
	}
	
	protected boolean addConditionListener(ConditionListener listener){
		if (! this.conditionListeners.contains(listener)){
			this.conditionListeners.add(listener);
			return true;
		}
		return false;
	}
	
	protected boolean removeConditionListener(ConditionListener listener){
		return this.conditionListeners.remove(listener);
	}
	
	protected void setState(boolean conditionState){
		this.state = conditionState;
		this.fireConditionChange(this);
	}

	public boolean checkConditionState(Object domainObject){
		return this.domainCondition.checkConditionState(domainObject);
	}
}
